home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / dev / c / libmpeg_src.lha / ordered2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-25  |  8.2 KB  |  326 lines

  1. /*  
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21. /* This file contains C code to implement an ordered dither. */
  22.  
  23. #include <config.h>
  24. #include "video.h"
  25. #include "proto.h"
  26. #include "dither.h"
  27.  
  28. #define DITH_SIZE 16
  29.  
  30.  
  31. /* Structures used to implement hybrid ordered dither/floyd-steinberg
  32.    dither algorithm.
  33. */
  34.  
  35. static unsigned char ***ditherPtr[DITH_SIZE];
  36.  
  37.  
  38. /*
  39.  *--------------------------------------------------------------
  40.  *
  41.  *  InitOrderedDither--
  42.  *
  43.  *    Structures intialized for ordered dithering. 
  44.  *
  45.  * Results:
  46.  *    None.
  47.  *
  48.  * Side effects:
  49.  *      None.
  50.  *
  51.  *--------------------------------------------------------------
  52.  */
  53.  
  54. void
  55. InitOrdered2Dither()
  56. {
  57.   unsigned char ****pos_2_cb;
  58.   unsigned char ***cb_2_cr;
  59.   unsigned char **cr_2_l;
  60.   int cb_val, cb_rval, cr_val, cr_rval, l_val, l_rval;
  61.   int i, j, pos;
  62.   int err_range, threshval;
  63.  
  64.   pos_2_cb = (unsigned char ****) malloc (DITH_SIZE*sizeof(unsigned char ***));
  65.   cb_2_cr = (unsigned char ***) malloc(CB_RANGE*sizeof(unsigned char **));
  66.   cr_2_l = (unsigned char **) malloc(CR_RANGE*sizeof(unsigned char *));
  67.  
  68.   for (pos=0; pos<DITH_SIZE; pos++) {
  69.     
  70.     pos_2_cb[pos] = (unsigned char ***) malloc(256*(sizeof(unsigned char **)));
  71.  
  72.     for (j=0; j<CB_RANGE; j++) {
  73.       cb_2_cr[j] = (unsigned char **) malloc(256*(sizeof(unsigned char *)));
  74.     }
  75.  
  76.     for (cb_val=0; cb_val<cb_values[0]; cb_val++) {
  77.       (pos_2_cb[pos])[cb_val] = cb_2_cr[0];
  78.     }
  79.  
  80.     for (cb_rval=0; cb_rval<(CB_RANGE-1); cb_rval++) {
  81.       err_range = cb_values[cb_rval+1] - cb_values[cb_rval];
  82.       threshval = ((pos*err_range)/DITH_SIZE)+cb_values[cb_rval];
  83.  
  84.       for (cb_val=cb_values[cb_rval]; cb_val<cb_values[cb_rval+1]; cb_val++) {
  85.     if (cb_val>threshval) (pos_2_cb[pos])[cb_val] = cb_2_cr[cb_rval+1];
  86.     else (pos_2_cb[pos])[cb_val] = cb_2_cr[cb_rval];
  87.       }
  88.     }
  89.  
  90.     for (cb_val=cb_values[CB_RANGE-1]; cb_val<256; cb_val++) {
  91.       (pos_2_cb[pos])[cb_val] = cb_2_cr[CB_RANGE-1];
  92.     }
  93.  
  94.     for (cb_rval=0; cb_rval<CB_RANGE; cb_rval++) {
  95.       
  96.       for (j=0; j<CR_RANGE; j++) {
  97.     cr_2_l[j] = (unsigned char *) malloc(256*(sizeof(unsigned char)));
  98.       }
  99.  
  100.       for (cr_val=0; cr_val < cr_values[0]; cr_val++) {
  101.     (cb_2_cr[cb_rval])[cr_val] = cr_2_l[0];
  102.       }
  103.  
  104.       for (cr_rval=0; cr_rval<(CR_RANGE-1); cr_rval++) {
  105.     err_range = cr_values[cr_rval+1] - cr_values[cr_rval];
  106.     threshval = ((pos*err_range)/DITH_SIZE)+cr_values[cr_rval];
  107.     
  108.     for (cr_val=cr_values[cr_rval]; cr_val<cr_values[cr_rval+1]; cr_val++) {
  109.       if (cr_val>threshval) (cb_2_cr[cb_rval])[cr_val] = cr_2_l[cr_rval+1];
  110.       else (cb_2_cr[cb_rval])[cr_val] = cr_2_l[cr_rval];
  111.     }
  112.       }
  113.       
  114.       for (cr_val=cr_values[CR_RANGE-1]; cr_val<256; cr_val++) {
  115.     (cb_2_cr[cb_rval])[cr_val] = cr_2_l[CR_RANGE-1];
  116.       }
  117.       
  118.       for (cr_rval=0; cr_rval<CR_RANGE; cr_rval++) {
  119.     
  120.     for (l_val = 0; l_val < lum_values[0]; l_val++) {
  121.       (cr_2_l[cr_rval])[l_val] = pixel[cb_rval+(cr_rval*CB_RANGE)+
  122.                         (0*CR_RANGE*CB_RANGE)];
  123.     }
  124.  
  125.     for (l_rval=0; l_rval<(LUM_RANGE-1); l_rval++) {
  126.       err_range = lum_values[l_rval+1] - lum_values[l_rval];
  127.       threshval = ((pos*err_range) /DITH_SIZE) + lum_values[l_rval];
  128.  
  129.       for (l_val = lum_values[l_rval]; l_val < lum_values[l_rval+1]; l_val++) {
  130.         if (l_val>threshval) (cr_2_l[cr_rval])[l_val] = 
  131.           pixel[cb_rval+(cr_rval*CB_RANGE)+((l_rval+1)*CR_RANGE*CB_RANGE)];
  132.         else (cr_2_l[cr_rval])[l_val] =
  133.           pixel[cb_rval+(cr_rval*CB_RANGE)+(l_rval*CR_RANGE*CB_RANGE)];
  134.       }
  135.     }
  136.  
  137.     for (l_val = lum_values[LUM_RANGE-1]; l_val < 256; l_val++) {
  138.       (cr_2_l[cr_rval])[l_val] = 
  139.         pixel[cb_rval+(cr_rval*CB_RANGE)+((LUM_RANGE-1)*CR_RANGE*CB_RANGE)];
  140.     }
  141.       }
  142.     }
  143.   }
  144.  
  145.   for (i=0; i<DITH_SIZE; i++) {
  146.     ditherPtr[i] = pos_2_cb[i];
  147.   }
  148. }
  149.  
  150. /*
  151.  *--------------------------------------------------------------
  152.  *
  153.  * Ordered2DitherImage --
  154.  *
  155.  *    Dithers an image using an ordered dither.
  156.  *    Assumptions made:
  157.  *      1) The color space is allocated y:cr:cb = 8:4:4
  158.  *      2) The spatial resolution of y:cr:cb is 4:1:1
  159.  *      The channels are dithered based on the standard
  160.  *      ordered dither pattern for a 4x4 area. 
  161.  *
  162.  * Results:
  163.  *    None.
  164.  *
  165.  * Side effects:
  166.  *    None.
  167.  *
  168.  *--------------------------------------------------------------
  169.  */
  170. void
  171. Ordered2DitherImage (lum, cr, cb, out, h, w)
  172.     unsigned char *lum;
  173.     unsigned char *cr;
  174.     unsigned char *cb;
  175.     unsigned char *out;
  176.     int w, h;
  177. {
  178.   unsigned char *l, *r, *b, *o1, *o2;
  179.   unsigned char *l2;
  180.   unsigned char L, R, B;
  181.   int i, j;
  182.   unsigned char ***dp0 = ditherPtr[0];
  183.   unsigned char ***dp2 = ditherPtr[2];
  184.   unsigned char ***dp4 = ditherPtr[4];
  185.   unsigned char ***dp6 = ditherPtr[6];
  186.   unsigned char ***dp8 = ditherPtr[8];
  187.   unsigned char ***dp10 = ditherPtr[10];
  188.   unsigned char ***dp12 = ditherPtr[12];
  189.   unsigned char ***dp14 = ditherPtr[14];
  190.   unsigned char ***dp1 = ditherPtr[1];
  191.   unsigned char ***dp3 = ditherPtr[3];
  192.   unsigned char ***dp5 = ditherPtr[5];
  193.   unsigned char ***dp7 = ditherPtr[7];
  194.   unsigned char ***dp9 = ditherPtr[9];
  195.   unsigned char ***dp11 = ditherPtr[11];
  196.   unsigned char ***dp13 = ditherPtr[13];
  197.   unsigned char ***dp15 = ditherPtr[15];
  198.  
  199.   l = lum;
  200.   l2 = lum+w;
  201.   r = cr;
  202.   b = cb;
  203.   o1 = out;
  204.   o2 = out+w;
  205.  
  206.   for (i=0; i<h; i+=4) {
  207.  
  208.     for (j=0; j<w; j+=8) {
  209.  
  210.       R = r[0]; B = b[0];
  211.  
  212.       L = l[0];
  213.       o1[0] = ((dp0[B])[R])[L];
  214.       L = l[1];
  215.       o1[1] = ((dp8[B])[R])[L];
  216.       L = l2[0];
  217.       o2[0] = ((dp12[B])[R])[L];
  218.       L = l2[1];
  219.       o2[1] = ((dp4[B])[R])[L];
  220.  
  221.       R = r[1]; B = b[1];
  222.  
  223.       L = l[2];
  224.       o1[2] = ((dp2[B])[R])[L];
  225.       L = l[3];
  226.       o1[3] = ((dp10[B])[R])[L];
  227.       L = l2[2];
  228.       o2[2] = ((dp14[B])[R])[L];
  229.       L = l2[3];
  230.       o2[3] = ((dp6[B])[R])[L];
  231.  
  232.       R = r[2]; B = b[2];
  233.  
  234.       L = l[4];
  235.       o1[4] = ((dp0[B])[R])[L];
  236.       L = l[5];
  237.       o1[5] = ((dp8[B])[R])[L];
  238.       L = l2[4];
  239.       o2[4] = ((dp12[B])[R])[L];
  240.       L = l2[5];
  241.       o2[5] = ((dp4[B])[R])[L];
  242.  
  243.       R = r[3]; B = b[3];
  244.  
  245.       L = l[6];
  246.       o1[6] = ((dp2[B])[R])[L];
  247.       L = l[7];
  248.       o1[7] = ((dp10[B])[R])[L];
  249.       L = l2[6];
  250.       o2[6] = ((dp14[B])[R])[L];
  251.       L = l2[7];
  252.       o2[7] = ((dp6[B])[R])[L];
  253.  
  254.       l += 8;
  255.       l2 += 8;
  256.       r += 4;
  257.       b += 4;
  258.       o1 += 8;
  259.       o2 += 8;
  260.     }
  261.  
  262.     l += w; l2 += w;
  263.     o1 += w; o2 += w;
  264.  
  265.     for (j=0; j<w; j+=8) {
  266.  
  267.       R = r[0]; B = b[0];
  268.  
  269.       L = l[0];
  270.       o1[0] = ((dp3[B])[R])[L];
  271.       L = l[1];
  272.       o1[1] = ((dp11[B])[R])[L];
  273.       L = l2[0];
  274.       o2[0] = ((dp15[B])[R])[L];
  275.       L = l2[1];
  276.       o2[1] = ((dp7[B])[R])[L];
  277.  
  278.       R = r[1]; B = b[1];
  279.  
  280.       L = l[2];
  281.       o1[2] = ((dp1[B])[R])[L];
  282.       L = l[3];
  283.       o1[3] = ((dp9[B])[R])[L];
  284.       L = l2[2];
  285.       o2[2] = ((dp13[B])[R])[L];
  286.       L = l2[3];
  287.       o2[3] = ((dp5[B])[R])[L];
  288.  
  289.       R = r[2]; B = b[2];
  290.  
  291.       L = l[4];
  292.       o1[4] = ((dp3[B])[R])[L];
  293.       L = l[5];
  294.       o1[5] = ((dp11[B])[R])[L];
  295.       L = l2[4];
  296.       o2[4] = ((dp15[B])[R])[L];
  297.       L = l2[5];
  298.       o2[5] = ((dp7[B])[R])[L];
  299.  
  300.       R = r[3]; B = b[3];
  301.  
  302.       L = l[6];
  303.       o1[6] = ((dp1[B])[R])[L];
  304.       L = l[7];
  305.       o1[7] = ((dp9[B])[R])[L];
  306.       L = l2[6];
  307.       o2[6] = ((dp13[B])[R])[L];
  308.       L = l2[7];
  309.       o2[7] = ((dp5[B])[R])[L];
  310.  
  311.       l += 8;
  312.       l2 += 8;
  313.       r += 4;
  314.       b += 4;
  315.       o1 += 8;
  316.       o2 += 8;
  317.     }
  318.  
  319.     l += w; l2 += w;
  320.     o1 += w; o2 += w;
  321.   }
  322. }
  323.  
  324.  
  325.   
  326.